package com.iss.umservice.common.xml;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class XmlNode
{
   
    private String name = null;
    
 
    private String value = null;
    

    private XmlNode parent = null;
    

    private Object data = null;
    

    private List<XmlNode> subNodes = new ArrayList<XmlNode>();
    
 
    private Map<String, String> attribues = new HashMap<String, String>();
    
    private List<String> attribueKeys = new ArrayList<String>();

    public boolean isValid()
    {
        return (name != null);
    }

    public XmlNode setAttribute(String qName, String value)
    {
        if (null == qName)
        {
            return this;
        }
        if (null == value)
        {
            value = "";
        }
        attribues.put(qName, value);
        if (!attribueKeys.contains(qName))
        {
            attribueKeys.add(qName);
        }
        
        return this;
    }
    
    /**
     * ȡ����ֵ
     * @param qName 
     * @return
     */
    public String getAttribute(String qName)
    {
        if (null == qName)
        {
            return null;
        }
        return (String)attribues.get(qName);
    }
    

    public XmlNode addSubNode(XmlNode node)
    {
        if (node == null)
        {
            return this;
        }
        
        if (subNodes.indexOf(node) < 0)
        {
            subNodes.add(node);
            if (node.parent != null)
            {
                node.parent.removeSubNode(node);
            }
            node.parent = this;
        }
        
        return this;
    }

    public List<XmlNode> getSubNodes()
    {
        return Collections.unmodifiableList(subNodes);
    }
    

    public void removeSubNode(XmlNode node)
    {
        if (node == null)
        {
            return;
        }
        
        subNodes.remove(node);
        node.parent = null; // �˴���Ҫ��setParent
    }
    

    public XmlNode[] getSubNodes(String name, String attrName, String attrValue)
    {
        if (null == name)
        {
            return null;
        }
        
        if (null == attrName || null == attrValue)
        {
            return getSubNodes(name);
        }
        
        XmlNode[] tmpNodes = getSubNodes(name);
        List<XmlNode> tmpList = new ArrayList<XmlNode>();
        for (int i = 0; i < tmpNodes.length; i++)
        {
            XmlNode tmpNode = tmpNodes[i];
            if (attrValue.equals(tmpNode.getAttribute(attrName)))
            {
                tmpList.add(tmpNode);
            }
        }
        
        XmlNode[] nodeArr = new XmlNode[tmpList.size()];
        
        nodeArr = (XmlNode[])tmpList.toArray(nodeArr);
        
        return nodeArr;
    }
    

    public XmlNode[] getSubNodes(String name)
    {
        if (null == name)
        {
            return null;
        }
        
        List<XmlNode> tmpList = new ArrayList<XmlNode>();
        for (int i = 0; i < subNodes.size(); i++)
        {
            XmlNode tmpNode = (XmlNode)subNodes.get(i);
            if ((tmpNode.getName() != null)
                    && (tmpNode.getName().equalsIgnoreCase(name)))
            {
                tmpList.add(tmpNode);
            }
        }
        
        XmlNode[] nodeArr = new XmlNode[tmpList.size()];
        
        nodeArr = (XmlNode[])tmpList.toArray(nodeArr);
        
        return nodeArr;
    }
    

    public XmlNode getSubNode(String name, int index)
    {
        XmlNode[] tmpNodes = getSubNodes(name);
        if ((null == tmpNodes) || (index < 0) || (index >= tmpNodes.length))
        {
            return new XmlNode();
        }
        else
        {
            return tmpNodes[index];
        }
    }
    

    public XmlNode getSubNode(String name)
    {
        return getSubNode(name, 0);
    }
    

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
    

    public String getValue()
    {
        return value;
    }
    
  
    public void setValue(String value)
    {
        this.value = value;
    }
    

    public XmlNode getParent()
    {
        return parent;
    }
    

    public void setParent(XmlNode parent)
    {
        XmlNode oldParent = this.parent;
        if ((oldParent != parent) && (null != oldParent))
        {
            oldParent.removeSubNode(this);
        }
        this.parent = parent;
        if (null != parent)
        {
            if (parent.subNodes.indexOf(this) < 0)
            {
                parent.subNodes.add(this);
            }
        }
    }
    

    public String toXML()
    {
        StringBuffer sb = new StringBuffer();
        String line = System.getProperty("line.separator");
        
        sb.append("<").append(name);
        
        if (!attribueKeys.isEmpty())
        {
            sb.append(" ");
            int size = attribueKeys.size();
            for (int i = 0; i < size; i++)
            {
                String key = (String)attribueKeys.get(i);
                sb.append(key).append("=\"");
                if (attribues.get(key) != null)
                {
                    sb.append(attribues.get(key));
                }
                sb.append("\"");
                if (i < (size - 1))
                {
                    sb.append(" ");
                }
            }
        }
        
        if (!subNodes.isEmpty())
        {
            sb.append(">").append(line);
            for (int i = 0; i < subNodes.size(); i++)
            {
                sb.append(((XmlNode)subNodes.get(i)).toXML());
            }
            
            sb.append("</").append(name).append(">");
        }
        else
        {
            if ((value != null) && (value.length() != 0))
            {
                sb.append(">")
                        .append(value)
                        .append("</")
                        .append(name)
                        .append(">");
            }
            else if (attribueKeys.isEmpty())
            {
                sb.append(">").append("</").append(name).append(">");
            }
            else
            {
                sb.append("/>");
            }
        }
        sb.append(line);
        
        return sb.toString();
    }
    
    /**
     * ȡЯ������
     * @return
     */
    public Object getData()
    {
        return data;
    }
    

    public void setData(Object data)
    {
        this.data = data;
    }
}